
open Chipmunk.Low_level

type t = cpBody * bool array

let radius = Config.cell_size /. 2.0

let create space = 
    let body = cpBodyNew Config.player_mass infinity in
    let () = cpBodySetPos ~body ~p:(cpv ~x:0.5 ~y:0.5) in
    let () = cpSpaceAddBody ~space ~body in
    let shape = cpCircleShapeNew ~body ~radius ~offset:(cpvzero()) in
    let () = cpShapeSetElasticity ~shape ~e:0.1 in
    let () = cpShapeSetFriction ~shape ~u:0.5 in
    let () = cpShapeSetCollisionType ~shape ~collision_type:1 in
    let () = cpSpaceAddShape ~space ~shape in
    (body, Array.make 4 false)

let show (body, keys) = 
	let pos = cpBodyGetPos body in
	Types.Data.List [
		Types.Data.Float pos.cp_x;
		Types.Data.Float pos.cp_y]

let draw_circle ~center:{cp_x=x; cp_y=y} ~r ~a =
	let pi = 4.0 *. atan 1.0 in
	let segs = 15 in
	let coef = 2.0 *. pi /. (float segs) in
	let () = GL.glBegin GL.GL_LINE_STRIP in
	let () = for n = 0 to segs do
		let rads = (float n) *. coef in
		GL.glVertex2
			(r *. cos(rads +. a) +. x)
			(r *. sin(rads +. a) +. y)
	done in
	let () = GL.glVertex2 x y in
	GL.glEnd()

let draw data = match data with
	| Types.Data.List [
		Types.Data.Float x;
		Types.Data.Float y] ->
			draw_circle	(cpv x y) radius 0.0
	| _ -> assert false

let step (body, keys) =
	let apply force = 
		cpBodyApplyImpulse body force (cpvzero())
	in begin
		if keys.(0) then apply (cpv ~x:0.0   ~y:40.0);
		if keys.(1) then apply (cpv ~x:(-.40.0) ~y:0.0);
		if keys.(2) then apply (cpv ~x:40.0  ~y:0.0);
		if keys.(3) then apply (cpv ~x:0.0   ~y:(-.40.0));
	end
	
let command (body, keys) cmd = match cmd with
	| Types.Data.String "+Up"    -> let () = keys.(0) <- true  in Types.Data.List[]
	| Types.Data.String "-Up"    -> let () = keys.(0) <- false in Types.Data.List[]
	| Types.Data.String "+Left"  -> let () = keys.(1) <- true  in Types.Data.List[]
	| Types.Data.String "-Left"  -> let () = keys.(1) <- false in Types.Data.List[]
	| Types.Data.String "+Right" -> let () = keys.(2) <- true  in Types.Data.List[]
	| Types.Data.String "-Right" -> let () = keys.(2) <- false in Types.Data.List[]
	| Types.Data.String "+Down"  -> let () = keys.(3) <- true  in Types.Data.List[]
	| Types.Data.String "-Down"  -> let () = keys.(3) <- false in Types.Data.List[]
	| _ -> Types.Data.List [Types.Data.String "Unknown command"; cmd]

